#include "common.h"
#include "config.h"
#include <math.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include "log.h"

// 线性插值函数
int linear_interpolate_int(int64_t x0, int64_t x1, int y0, int y1, int64_t x)
{
    if (x0 == x1) {
        return y0;  // 避免除以零
    }
    return y0 + (y1 - y0) * (x - x0) / (x1 - x0);
}

// 生成目标数据：线性插值
void generate_target_data_with_linear_interpolation(
    int original_data_points,  // 原始数据点数
    scale_t *original_data,    // 原始数据数组
    int target_data_points,    // 目标数据点数
    scale_t *target_data       // 目标数据数组
)
{
    // 如果源和目标数组相同，且目标数据点数大于原始数据点数，需要额外处理
    if (original_data == target_data && target_data_points > original_data_points) {
        // 创建一个临时数组来存储目标数据
        scale_t *temp_data = (scale_t *)malloc(target_data_points * sizeof(scale_t));
        if (temp_data == NULL) {
            fprintf(stderr, "Memory allocation failed!\n");
            return;
        }

        // 调用自身，将结果写入临时数组
        generate_target_data_with_linear_interpolation(
            original_data_points, original_data, target_data_points, temp_data);

        // 将临时数组的内容复制回目标数组
        for (int i = 0; i < target_data_points; i++) {
            target_data[i] = temp_data[i];
        }

        // 释放临时数组
        free(temp_data);
        return;
    }

    // 计算原始数据的时间范围
    int64_t original_time_min = original_data[0].time;
    int64_t original_time_max = original_data[original_data_points - 1].time;

    for (int i = 0; i < target_data_points; i++) {
        // 计算目标时间点 (等间隔插值)
        int64_t target_time = original_time_min + (i * (original_time_max - original_time_min)) / (target_data_points - 1);
        target_data[i].time = target_time;

        // 如果是最后一个点，直接使用原始数据的最后一个值
        if (i == target_data_points - 1) {
            target_data[i].pixel_y = original_data[original_data_points - 1].pixel_y;
            continue;
        }

        // 查找目标时间点前后的原始时间点
        int idx1 = 0;
        int idx2 = 0;

        // 找到最接近 target_time 的 idx1 和 idx2
        for (int j = 0; j < original_data_points - 1; j++) {
            if (original_data[j].time <= target_time && original_data[j + 1].time > target_time) {
                idx1 = j;
                idx2 = j + 1;
                break;
            }
        }

        // 如果 idx2 超过数组范围，将其限制在有效范围
        if (idx2 >= original_data_points) {
            idx2 = idx1;  // 使 idx2 保持在 idx1 上，防止越界
        }

        // 如果 idx1 和 idx2 相同，直接使用 pixel_y（或 y2）
        if (original_data[idx1].time == original_data[idx2].time) {
            target_data[i].pixel_y = original_data[idx1].pixel_y;  // 或者 original_data[idx2].pixel_y
        }
        else {
            // 直接计算线性插值的结果，并返回
            target_data[i].pixel_y = linear_interpolate_int(
                original_data[idx1].time, original_data[idx2].time,
                original_data[idx1].pixel_y, original_data[idx2].pixel_y,
                target_time);
        }
    }
}

#define CRC32_POLY 0x04C11DB7

// 全局查找表
static uint32_t crc32_table[256];

// 初始化查找表，采用大端方式计算
static void init_crc32_table(void)
{
    uint32_t c;
    for (int i = 0; i < 256; i++) {
        c = (uint32_t)i << 24;
        for (int j = 0; j < 8; j++) {
            if (c & 0x80000000)
                c = (c << 1) ^ CRC32_POLY;
            else
                c <<= 1;
        }
        crc32_table[i] = c;
    }
}

// 使用查表法计算 CRC32 MPEG
uint32_t pro_crc32_mpeg(uint8_t *dataIn, uint32_t datalen)
{
    // 确保查找表已经初始化
    if (crc32_table[1] == 0) {
        init_crc32_table();
    }

    uint32_t crc = 0xFFFFFFFF;
    while (datalen--) {
        // 取最高字节与当前数据字节异或得到查表索引
        uint8_t index = (crc >> 24) ^ *dataIn++;
        crc = (crc << 8) ^ crc32_table[index];
    }
    return crc;
}

void get_platform_time_stamp(unsigned char *ptime_stamp)
{
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);

    uint32_t sec = (uint32_t)ts.tv_sec;
    uint16_t msec = (uint16_t)(ts.tv_nsec / 1000000);

    // 小端存储秒数（4字节）
    for (int i = 0; i < 4; ++i) {
        ptime_stamp[i] = sec >> (8 * i);
    }
    // 小端存储毫秒数（2字节）
    for (int i = 0; i < 2; ++i) {
        ptime_stamp[4 + i] = msec >> (8 * i);
    }
}

int64_t change_platform_time_stamp_to_milliseconds(const unsigned char *ptime_stamp)
{
    // 秒数（4字节）
    uint32_t sec = 0;
    for (int i = 0; i < 4; ++i) {
        sec |= (uint32_t)(ptime_stamp[i] << (8 * i));
    }
    // 毫秒数（2字节）
    uint16_t msec = 0;
    for (int i = 0; i < 2; ++i) {
        msec |= (uint16_t)(ptime_stamp[4 + i] << (8 * i));
    }
    return (int64_t)sec * 1000 + msec;
}

int compare_timestamp(const void *a, const void *b)
{
    const unsigned char *t1 = a;
    const unsigned char *t2 = b;

    // 前 6 个字段按顺序比较
    int cmp = memcmp(t1, t2, 6);
    if (cmp != 0)
        return cmp > 0 ? 1 : -1;

    // 毫秒字段：Byte7（低字节）在前，Byte8（高字节）在后
    unsigned int ms1 = t1[6] | (t1[7] << 8);
    unsigned int ms2 = t2[6] | (t2[7] << 8);

    if (ms1 > ms2)
        return 1;
    else if (ms1 < ms2)
        return -1;
    else
        return 0;
}

// 封装函数：获取当前系统时间并转换为毫秒
int64_t get_current_time_in_milliseconds(void)
{
    struct timespec current_time;
    if (clock_gettime(CLOCK_REALTIME, &current_time) != 0) {
        // 如果获取时间失败，可以根据需要进行错误处理
        return 0;
    }
    return current_time.tv_sec * 1000LL + current_time.tv_nsec / 1000000LL;
}

void get_timeinfo_from_milliseconds(int64_t milliseconds, struct tm *timeinfo)
{
    time_t seconds = milliseconds / 1000;
    localtime_r(&seconds, timeinfo);
}

// 封装函数：将毫秒值转换为 "YYYY-MM-DD HH:MM:SS.mmm" 格式的字符串
char *format_time_ms(int64_t ms, char *buffer, size_t buf_size)
{
    if (!buffer || buf_size < 1)
        return NULL;

    // 分解总毫秒值为秒和毫秒部分
    time_t sec = ms / 1000;
    int millis = ms % 1000;

    // 使用线程安全的 localtime_r（也可以用 localtime，但不是线程安全的）
    struct tm tm_info;
    localtime_r(&sec, &tm_info);

    // 格式化日期和时间部分 "YYYY-MM-DD HH:MM:SS"
    size_t len = strftime(buffer, buf_size, "%Y-%m-%d %H:%M:%S", &tm_info);
    if (len == 0)
        return buffer;  // 如果空间不足或格式化失败，则直接返回

    // 拼接毫秒部分，确保不超出缓冲区
    snprintf(buffer + len, buf_size - len, ".%03d", millis);

    return buffer;
}

void timestamp_format_conversion(const char *radar_timestamp, char *platform_timestamp)
{
    struct tm t = {0};
    t.tm_year = radar_timestamp[0] + 100;
    t.tm_mon = radar_timestamp[1] - 1;
    t.tm_mday = radar_timestamp[2];
    t.tm_hour = radar_timestamp[3];
    t.tm_min = radar_timestamp[4];
    t.tm_sec = radar_timestamp[5];
    t.tm_isdst = -1;  // 自动判断夏令时
    time_t time = mktime(&t);
    memcpy(platform_timestamp, &time, 4);                    // 前 4 字节为秒数
    memcpy(platform_timestamp + 4, &radar_timestamp[6], 2);  // 后 2 字节为毫秒数
}

void print_radar_timestramp(const char *radar_timestamp)
{
    struct tm t = {0};
    t.tm_year = radar_timestamp[0] + 100;
    t.tm_mon = radar_timestamp[1] - 1;
    t.tm_mday = radar_timestamp[2];
    t.tm_hour = radar_timestamp[3];
    t.tm_min = radar_timestamp[4];
    t.tm_sec = radar_timestamp[5];
    t.tm_isdst = -1;  // 自动判断夏令时
    time_t time = mktime(&t);
    char buf[32];
    strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &t);

    printf("Radar timestamp: %s:%03d\n", buf, (radar_timestamp[6] | (radar_timestamp[7] << 8)));
}

// 将 UUID 的前 3 段提取并转换为 int64
int64_t uuid_to_int64(const char *uuid)
{
    char buffer[128] = {0};  // 用于存储拼接后的字符串
    int segment_count = 0;
    const char *ptr = uuid;

    // 提取前 3 段
    while (*ptr && segment_count < 3) {
        if (*ptr == '-') {
            segment_count++;
        }
        else {
            // 将字符追加到 buffer
            size_t len = strlen(buffer);
            buffer[len] = *ptr;
            buffer[len + 1] = '\0';
        }
        ptr++;
    }

    // 将拼接后的字符串转换为 int64
    char *endptr;
    int64_t result = (strtoll(buffer, &endptr, 16) & 0x7FFFFFFFFFFFFFFF);  // 16 表示十六进制
    if (*endptr != '\0') {
        fprintf(stderr, "Invalid UUID format: %s\n", uuid);
        return -1;
    }

    return result;
}

// 将字符串直接转换为 int64
int64_t str_to_int64(const char *str)
{
    char *endptr;
    int64_t result = strtoll(str, &endptr, 10);  // 10 表示十进制
    if (*endptr != '\0') {
        fprintf(stderr, "Invalid number format: %s\n", str);
        return -1;
    }
    return result;
}

int64_t parse_to_int64(const char *uuid)
{
    // 判断输入格式
    if (strchr(uuid, '-') != NULL) {
        // UUID 格式
        return uuid_to_int64(uuid);
    }
    else {
        // 数字格式
        return str_to_int64(uuid);
    }
}

// 设置指定位置的位
void set_bit(Bitmap *bmp, int row, int col)
{
    if (!bmp || row < 0 || row >= MAX_ROWS || col < 0 || col >= MAX_COLS)
        return;
    if (bmp->data[row][col] == 1)
        return;
    bmp->data[row][col] = 1;
    bmp->count++;
}

// 清除指定位置的位
void clear_bit(Bitmap *bmp, int row, int col)
{
    if (!bmp || row < 0 || row >= MAX_ROWS || col < 0 || col >= MAX_COLS)
        return;
    if (bmp->data[row][col] == 0)
        return;
    bmp->data[row][col] = 0;
    bmp->count--;
}

// 清除所有位
void clear_all_bits(Bitmap *bmp)
{
    if (!bmp)
        return;
    memset(bmp->data, 0, BITMAP_SIZE);
}

// 获取指定位置的位值，返回 0 或 1
int get_bit(const Bitmap *bmp, int row, int col)
{
    if (!bmp || row < 0 || row >= MAX_ROWS || col < 0 || col >= MAX_COLS)
        return 0;
    return bmp->data[row][col];
}

int get_valid_bit_count(const Bitmap *bmp)
{
    if (!bmp)
        return 0;
    return bmp->count;
}

void print_bitmap(const Bitmap *bmp)
{
    if (!bmp)
        return;

    // 打印位图
    for (int i = 0; i < MAX_ROWS; i++) {
        for (int j = 0; j < MAX_COLS; j++) {
            int bit = get_bit(bmp, i, j);
            if (bit == 1)
                printf("\033[31mX\033[0m ");  // 如果是1，打印绿色，再重置颜色
            else
                printf("\033[32m0\033[0m ");
        }
        printf("\n");
    }
    printf("\n");
}

char *get_bitmap_string(const Bitmap *bmp, char *buffer, size_t size)
{
    int buf_size = MAX_ROWS * (MAX_COLS * 16 + 1) + 1;
    if (!bmp || !buffer || size < buf_size)
        return NULL;

    buffer[0] = '\0';
    int offset = 0;

    // 格式化每一行
    for (int i = 0; i < MAX_ROWS; i++) {
        for (int j = 0; j < MAX_COLS; j++) {
            int bit = get_bit(bmp, i, j);
            if (bit == 1) {
                // 如果是1，打印红色 X（使用 ANSI 转义码），后面有空格分隔
                offset += snprintf(buffer + offset, buf_size - offset, "X ");
            }
            else {
                // 否则打印 0
                offset += snprintf(buffer + offset, buf_size - offset, "0 ");
            }
        }
        offset += snprintf(buffer + offset, buf_size - offset, "\n");
    }
    return buffer;
}

void write_bitmap_to_file(const Bitmap *bmp, const char *filename)
{
    if (!bmp || !filename)
        return;

    // 预估缓冲区大小：每个像素最多使用 16 个字符，再加上每行一个换行符
    int buf_size = MAX_ROWS * (MAX_COLS * 16 + 1) + 1;
    char *buffer = malloc(buf_size);
    if (!buffer)
        return;

    buffer[0] = '\0';
    int offset = 0;

    // 格式化每一行
    for (int i = 0; i < MAX_ROWS; i++) {
        for (int j = 0; j < MAX_COLS; j++) {
            int bit = get_bit(bmp, i, j);
            if (bit == 1) {
                // 如果是1，打印红色 X（使用 ANSI 转义码），后面有空格分隔
                offset += snprintf(buffer + offset, buf_size - offset, "X ");
            }
            else {
                // 否则打印 0
                offset += snprintf(buffer + offset, buf_size - offset, "0 ");
            }
        }
        offset += snprintf(buffer + offset, buf_size - offset, "\n");
    }

    // 将格式化好的字符串写入文件
    write_log(filename, " ", buffer, NULL);
    free(buffer);
}

void reverse(const void *src, void *dst, size_t len)
{
    // 如果源地址和目的地址相同，则进行原地转换
    if (src == dst) {
        unsigned char *p = dst;
        for (size_t i = 0; i < len / 2; i++) {
            unsigned char temp = p[i];
            p[i] = p[len - 1 - i];
            p[len - 1 - i] = temp;
        }
    }
    else {
        // 非原地转换：从源数据反转复制到目的地址
        const unsigned char *s = src;
        unsigned char *d = dst;
        for (size_t i = 0; i < len; i++) {
            d[i] = s[len - 1 - i];
        }
    }
}

void *print_thread_id(void)
{
    pthread_t tid = pthread_self();
    printf("当前线程 pthread_self ID: %lu\n", (unsigned long)tid);
    return NULL;
}

void copy_str_with_padding(char *dest, const char *src, size_t size)
{
    size_t len = strlen(src);
    if (len >= size) {
        // 如果字符数大于或等于 size，则只拷贝前 size 个字符
        memcpy(dest, src, size);
    }
    else {
        // 拷贝原字符串，然后用空格补齐
        memcpy(dest, src, len);
        memset(dest + len, ' ', size - len);
    }
    // 如果需要以 '\0' 结尾，则需要 dest 至少有 size+1 的空间
    // dest[size] = '\0';
}

bool float_equal(double a, double b, double epsilon)
{
    return fabs(a - b) < epsilon;
}

/* Base64 字符表 */
static const char b64_table[] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "abcdefghijklmnopqrstuvwxyz"
    "0123456789+/";

/**
 * 将 data[0..input_length-1] 编码成 Base64，返回的字符串以 '\0' 结尾。
 * *output_length 会被设置成不包含末尾 '\0' 的输出长度（即 strlen）。
 * 调用者负责 free() 返回的内存。
 */
char *base64_encode(const unsigned char *data,
                    size_t input_length,
                    size_t *output_length)
{
    // 4 个 Base64 字符编码 3 个字节
    *output_length = 4 * ((input_length + 2) / 3);
    char *encoded = malloc(*output_length + 1);
    if (!encoded)
        return NULL;

    size_t i = 0, j = 0;
    while (i + 2 < input_length) {
        uint32_t triple = (data[i] << 16) | (data[i + 1] << 8) | data[i + 2];
        encoded[j++] = b64_table[(triple >> 18) & 0x3F];
        encoded[j++] = b64_table[(triple >> 12) & 0x3F];
        encoded[j++] = b64_table[(triple >> 6) & 0x3F];
        encoded[j++] = b64_table[triple & 0x3F];
        i += 3;
    }

    // 处理剩余 1 或 2 字节
    if (i < input_length) {
        uint32_t octet_a = data[i++];
        uint32_t octet_b = (i < input_length) ? data[i++] : 0;
        uint32_t triple = (octet_a << 16) | (octet_b << 8);
        encoded[j++] = b64_table[(triple >> 18) & 0x3F];
        encoded[j++] = b64_table[(triple >> 12) & 0x3F];
        if (i > input_length) {
            encoded[j++] = '=';
        }
        else {
            encoded[j++] = b64_table[(triple >> 6) & 0x3F];
        }
        encoded[j++] = '=';
    }

    encoded[j] = '\0';
    return encoded;
}

/**
 * 读取整个文件到内存，然后调用 base64_encode。
 * 返回的字符串以 '\0' 结尾，调用者负责 free()。
 * 失败时返回 NULL。
 */
char *file_to_base64(const char *filename)
{
    FILE *fp = fopen(filename, "rb");
    if (!fp)
        return NULL;

    // 计算文件大小
    fseek(fp, 0, SEEK_END);
    long file_size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    if (file_size < 0) {
        fclose(fp);
        return NULL;
    }
    // 读取文件内容
    unsigned char *buffer = malloc(file_size);
    if (!buffer) {
        fclose(fp);
        return NULL;
    }
    if (fread(buffer, 1, file_size, fp) != (size_t)file_size) {
        free(buffer);
        fclose(fp);
        return NULL;
    }
    fclose(fp);
    // 编码
    size_t b64_len;
    char *b64 = base64_encode(buffer, file_size, &b64_len);
    free(buffer);
    return b64;
}

void ip_bytes_to_str(const uint8_t ip[4], char out[16])
{
    // out 至少要能容纳 "255.255.255.255\0" 共 16 字节
    snprintf(out, 16, "%u.%u.%u.%u",
             ip[0], ip[1], ip[2], ip[3]);
}

int hex_to_str(const uint8_t *data, size_t len, char *out, size_t out_len)
{
    size_t required = len * 2 + 1;
    if (out_len < required) {
        return -1;  // 缓冲区不足
    }

    static const char hex_digits[] = "0123456789ABCDEF";
    for (size_t i = 0; i < len; i++) {
        uint8_t byte = data[i];
        out[2 * i] = hex_digits[(byte >> 4) & 0x0F];
        out[2 * i + 1] = hex_digits[byte & 0x0F];
    }
    out[len * 2] = '\0';
    return 0;
}

int get_time_bytes(uint8_t *buf, size_t buf_len)
{
    if (buf_len < 8) {
        return -1;
    }

    struct timeval tv;
    struct tm tm;

    /* 获取系统时间（秒 + 微秒）*/
    if (gettimeofday(&tv, NULL) != 0) {
        return -1;
    }
    /* 转成本地年月日时分秒 */
    if (localtime_r(&tv.tv_sec, &tm) == NULL) {
        return -1;
    }

    int year_offset = tm.tm_year + 1900 - 2000;
    if (year_offset < 0)
        year_offset = 0;
    if (year_offset > 255)
        year_offset = 255;

    /* 毫秒 = tv.tv_usec / 1000, 保证在 [0,999] */
    int msec = (tv.tv_usec / 1000) % 1000;

    buf[0] = (uint8_t)year_offset;          /* 年偏移 */
    buf[1] = (uint8_t)(tm.tm_mon + 1);      /* 月：tm_mon 范围 0–11 */
    buf[2] = (uint8_t)tm.tm_mday;           /* 日 */
    buf[3] = (uint8_t)tm.tm_hour;           /* 时 */
    buf[4] = (uint8_t)tm.tm_min;            /* 分 */
    buf[5] = (uint8_t)tm.tm_sec;            /* 秒 */
    buf[6] = (uint8_t)(msec & 0xFF);        /* 毫秒低字节 */
    buf[7] = (uint8_t)((msec >> 8) & 0xFF); /* 毫秒高字节 */

    return 0;
}

double big_endian_to_double(const uint8_t *buf)
{
    uint8_t temp[8];
    for (int i = 0; i < 8; ++i) {
        temp[i] = buf[7 - i];  // 反转字节顺序
    }

    double result;
    memcpy(&result, temp, sizeof(result));
    return result;
}

void double_to_big_endian(double value, uint8_t *buf)
{
    uint8_t *p = (uint8_t *)&value;
    for (int i = 0; i < 8; ++i) {
        buf[i] = p[7 - i];
    }
}

// 将字节数组转换为十六进制字符串（使用外部提供的缓冲区）
void bytes_to_hex_string(const unsigned char *data, size_t length, char *hex_string_buf, size_t buf_size)
{
    if (!data || !hex_string_buf || buf_size < length * 2 + 1) {
        // 缓冲区不足或参数无效
        fprintf(stderr, "Invalid parameters or buffer too small\n");
        return;
    }

    for (size_t i = 0; i < length; i++) {
        sprintf(hex_string_buf + i * 2, "%02X", data[i]);
    }

    hex_string_buf[length * 2] = '\0';  // 添加结束符
}
